package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import javassist.bytecode.stackmap.BasicBlock;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @author hm
 * @version 1.0
 * @date Created in 2024/7/8 14:30
 */
/**
 * 自定义切面，实现公共字段自动填充处理逻辑
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    /**
     * 自定义注解AutoFillAspect注解
     * 定义切入点
     */
    @Pointcut(" @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}

    /**
     * 自动填充
     * 前置通知，在通知中进行公共字段的赋值
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            Class<?> aClass = arg.getClass();
            String name = aClass.getPackage().getName();
            if (name.equals("com.sky.entity")){
                System.out.println(aClass);
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();
                AutoFill annotation = method.getAnnotation(AutoFill.class);
                OperationType value = annotation.value();
                System.out.println(value);
                try {
                    Method setCreateTime = aClass.getDeclaredMethod("setCreateTime", LocalDateTime.class);
                    Method setUpdateTime = aClass.getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                    Method setCreateUser = aClass.getDeclaredMethod("setCreateUser", Long.class);
                    Method setUpdateUser = aClass.getDeclaredMethod("setUpdateUser", Long.class);
                    LocalDateTime now = LocalDateTime.now();
                    Long currentId = BaseContext.getCurrentId();
                    switch (value){
                        case INSERT:
                            setCreateTime.invoke(arg, now);
                            setUpdateTime.invoke(arg, now);
                            setCreateUser.invoke(arg,currentId);
                            setUpdateUser.invoke(arg,currentId);
                            break;
                        case UPDATE:
                            setUpdateTime.invoke(arg, now);
                            setUpdateUser.invoke(arg,currentId);
                    }
                }catch (Exception e){
                    throw new RuntimeException(e);
                }
            }

        }

    }
}